home *** CD-ROM | disk | FTP | other *** search
- /**********************************************************************
- * ISO MPEG Audio Subgroup Software Simulation Group (1996)
- * ISO 13818-3 MPEG-2 Audio Encoder - Lower Sampling Frequency Extension
- *
- * $Id: encode.c,v 1.2 1998/10/05 17:06:47 larsi Exp $
- *
- * $Log: encode.c,v $
- * Revision 1.2 1998/10/05 17:06:47 larsi
- * *** empty log message ***
- *
- * Revision 1.1.1.1 1998/10/05 14:47:17 larsi
- *
- * Revision 1.1 1996/02/14 04:04:23 rowlands
- * Initial revision
- *
- * Received from Mike Coleman
- **********************************************************************/
-
-
- #include "common.h"
- #include "encoder.h"
-
-
- /************************************************************************
- *
- * read_samples()
- *
- * PURPOSE: reads the PCM samples from a file to the buffer
- *
- * SEMANTICS:
- * Reads #samples_read# number of shorts from #musicin# filepointer
- * into #sample_buffer[]#. Returns the number of samples read.
- *
- ************************************************************************/
-
- unsigned long read_samples(musicin, sample_buffer, num_samples, frame_size)
- FILE *musicin;
- short sample_buffer[2304];
- unsigned long num_samples, frame_size;
- {
- unsigned long samples_read;
- static unsigned long samples_to_read;
- static char init = TRUE;
- extern int swapbytes; /* if TRUE then force swapping of byte order */
-
- if (init) {
- samples_to_read = num_samples;
- init = FALSE;
- }
- if (samples_to_read >= frame_size)
- samples_read = frame_size;
- else
- samples_read = samples_to_read;
- if ((samples_read =
- fread(sample_buffer, sizeof(short), (int)samples_read, musicin)) == 0)
- { /* printf("Hit end of audio data\n"); */ }
- /*
- Samples are big-endian. If this is a little-endian machine
- we must swap
- */
- if ( NativeByteOrder == order_unknown )
- {
- NativeByteOrder = DetermineByteOrder();
- if ( NativeByteOrder == order_unknown )
- {
- fprintf( stderr, "byte order not determined\n" );
- exit( 1 );
- }
- }
- if (!iswav && ( NativeByteOrder == order_littleEndian ))
- SwapBytesInWords( sample_buffer, samples_read );
-
- if (swapbytes==TRUE)
- SwapBytesInWords( sample_buffer, samples_read );
-
- samples_to_read -= samples_read;
- if (samples_read < frame_size && samples_read > 0) {
- /* printf("Insufficient PCM input for one frame - fillout with zeros\n"); */
- for (; samples_read < frame_size; sample_buffer[samples_read++] = 0);
- samples_to_read = 0;
- }
- return(samples_read);
- }
-
- /************************************************************************
- *
- * get_audio()
- *
- * PURPOSE: reads a frame of audio data from a file to the buffer,
- * aligns the data for future processing, and separates the
- * left and right channels
- *
- *
- ************************************************************************/
-
- unsigned long get_audio( musicin, bufferL,bufferR, num_samples, stereo, info )
- FILE *musicin;
- /*
- short FAR buffer[2][1152];
- */
- short FAR bufferL[1152],bufferR[1152];
- unsigned long num_samples;
- int stereo;
- layer *info;
- {
- int j;
- short insamp[3176];
- unsigned long samples_read;
- int lay;
- extern int autoconvert;
-
- lay = info->lay;
-
- /* pad with zeros in case we hit EOF */
- memset((char *) insamp, 0, sizeof(insamp));
-
- if ( (lay == 3) && (info->version == 0) ) /* ie MPEG-2 LSF */
- {
- if ( stereo == 2 )
- {
- samples_read = read_samples( musicin, insamp, num_samples,
- (unsigned long) 1152 );
- for ( j = 0; j < 576; j++ )
- {
- bufferL[j] = insamp[2 * j];
- bufferR[j] = insamp[2 * j + 1];
- }
- }
- else
- {
- samples_read = read_samples( musicin, insamp, num_samples,
- (unsigned long) 576 );
- for ( j = 0; j < 576; j++ )
- {
- bufferL[j] = insamp[j];
- bufferR[j] = 0;
- }
- }
- }
- else
- /* MPEG 1 */
- {
- if(stereo == 2){ /* layer 2 (or 3), stereo */
- samples_read = read_samples(musicin, insamp, num_samples,
- (unsigned long) 2304);
- for(j=0;j<1152;j++) {
- bufferL[j] = insamp[2*j];
- bufferR[j] = insamp[2*j+1];
-
- }
- }
- else { /* layer 2 (or 3), mono */
- if (autoconvert==TRUE) { /* downconvert from a stereo file into a mono buffer */
- samples_read = read_samples(musicin, insamp, num_samples,
- (unsigned long) 2304);
- for(j=0;j<1152;j++){
- bufferL[j] = insamp[2*j];
- bufferR[j] = 0;
- }
- }
- else {
- samples_read = read_samples(musicin, insamp, num_samples,
- (unsigned long) 1152);
- for(j=0;j<1152;j++){
- bufferL[j] = insamp[j];
- bufferR[j] = 0;
- }
- }
- }
- }
- return(samples_read);
- }
-
- /************************************************************************
- *
- * window_subband()
- *
- * PURPOSE: Overlapping window on PCM samples
- *
- * SEMANTICS:
- * 32 16-bit pcm samples are scaled to fractional 2's complement and
- * concatenated to the end of the window buffer #x#. The updated window
- * buffer #x# is then windowed by the analysis window #c# to produce the
- * windowed sample #z#
- *
- ************************************************************************/
-
- extern double enwindow[];
-
- void window_subband(buffer, z, k)
- short **buffer;
- double z[HAN_SIZE];
- int k;
- {
- typedef double FAR XX[2][HAN_SIZE];
- static XX FAR *x;
- double *xk;
- int i;
- static int off[2] = {0,0};
- static char init = 0;
- if (!init) {
- x = (XX FAR *) mem_alloc(sizeof(XX),"x");
- memset(x, 0, 2*HAN_SIZE);
- init = 1;
- }
- xk=(*x)[k];
-
- /* replace 32 oldest samples with 32 new samples */
- for (i=0;i<32;i++) /*(*x)[k]*/xk[31-i+off[k]] = (double) *(*buffer)++/SCALE;
- /* shift samples into proper window positions */
- for (i=0;i<HAN_SIZE;i++) z[i] = xk[(i+off[k])&(HAN_SIZE-1)] * enwindow[i];
- off[k] += 480; /*offset is modulo (HAN_SIZE-1)*/
- off[k] &= HAN_SIZE-1;
-
- }
-
- /************************************************************************
- *
- * filter_subband()
- *
- * PURPOSE: Calculates the analysis filter bank coefficients
- *
- * SEMANTICS:
- * The windowed samples #z# is filtered by the digital filter matrix #m#
- * to produce the subband samples #s#. This done by first selectively
- * picking out values from the windowed samples, and then multiplying
- * them by the filter matrix, producing 32 subband samples.
- *
- ************************************************************************/
-
-
- void
- create_dct_matrix( filter )
- double filter[16][32];
- {
- register int i,k;
-
- for (i=0; i<16; i++)
- for (k=0; k<32; k++) {
- filter[i][k] = cos((double)((2*i+1)*k*PI64));
- }
- }
-
- void
- IDCT32( xin, xout )
- double *xin, *xout;
- {
- int i,j;
- double s0, s1;
- typedef double MM[16][32];
- static MM FAR * m = 0;
- if( m==0 ) {
- m = (MM FAR *)mem_alloc(sizeof(MM),"filter");
- create_dct_matrix( *m );
- }
- for( i=0; i<16; i++ ) {
- s0 = s1 = 0.0;
- for( j=0; j<32; j+=2 ) {
- s0 += (*m)[i][j]*xin[j+0];
- s1 += (*m)[i][j+1]*xin[j+1];
- }
- xout[i] = s0+s1;
- xout[31-i] = s0-s1;
- }
- }
-
- void filter_subband(z,s)
- double FAR z[HAN_SIZE], s[SBLIMIT];
- {
- double y[64],yprime[32];
- int i;
- double *zi;
-
- zi = z;
- for( i=0; i<64; i++ ) {
- y[ i ] = *zi + zi[ 64 ] + zi[ 128 ] + zi[ 192 ] +
- zi[ 256 ] + zi[ 320 ] + zi[ 384 ] + zi[ 448 ];
- zi++;
- }
-
- {
- yprime[0] = y[16];
- for( i=1; i<=16; i++ ) yprime[i] = y[i+16]+y[16-i];
- for( i=17; i<=31; i++ ) yprime[i] = y[i+16]-y[80-i];
- IDCT32( yprime, s );
- }
- }
-
-
- /************************************************************************
- * encode_info()
- *
- * PURPOSE: Puts the syncword and header information on the output
- * bitstream.
- *
- ************************************************************************/
-
- void encode_info(fr_ps,bs)
- frame_params *fr_ps;
- Bit_stream_struc *bs;
- {
- layer *info = fr_ps->header;
-
- putbits(bs,0xfff,12); /* syncword 12 bits */
- put1bit(bs,info->version); /* ID 1 bit */
- putbits(bs,4-info->lay,2); /* layer 2 bits */
- put1bit(bs,!info->error_protection); /* bit set => no err prot */
- putbits(bs,info->bitrate_index,4);
- putbits(bs,info->sampling_frequency,2);
- put1bit(bs,info->padding);
- put1bit(bs,info->extension); /* private_bit */
- putbits(bs,info->mode,2);
- putbits(bs,info->mode_ext,2);
- put1bit(bs,info->copyright);
- put1bit(bs,info->original);
- putbits(bs,info->emphasis,2);
- }
-
- /************************************************************************
- *
- * mod()
- *
- * PURPOSE: Returns the absolute value of its argument
- *
- ************************************************************************/
-
- double mod(a)
- double a;
- {
- return (a > 0) ? a : -a;
- }
-
-
-
- /************************************************************************
- *
- * encode_CRC
- *
- ************************************************************************/
-
- void encode_CRC(crc, bs)
- unsigned int crc;
- Bit_stream_struc *bs;
- {
- putbits(bs, crc, 16);
- }
-